package com.baoyouqun.controller.union;

import cn.dev33.satoken.annotation.SaIgnore;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.lang.Validator;
import cn.hutool.core.lang.tree.Tree;
import com.alibaba.cola.dto.Response;
import com.alibaba.cola.dto.SingleResponse;
import com.alibaba.fastjson2.JSONObject;
import com.baoyouqun.API.sms.SmsService;
import com.baoyouqun.API.wx.BindWechatDTO;
import com.baoyouqun.API.wx.RegisterWechatDTO;
import com.baoyouqun.API.wx.WxLoginResultDTO;
import com.baoyouqun.API.wx.WxMiniLoginService;
import com.baoyouqun.domain.CreateCmd.UserCreateCmd;
import com.baoyouqun.domain.VO.*;
import com.baoyouqun.domain.cmd.LoginCmd;
import com.baoyouqun.domain.cmd.SmsLoginCmd;
import com.baoyouqun.domain.cmd.UpdatePasswordCmd;
import com.baoyouqun.entity.User;
import com.baoyouqun.service.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import jakarta.annotation.Resource;
import jakarta.validation.Valid;
import org.apache.poi.util.StringUtil;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Objects;

@SaIgnore
@RestController
@RequestMapping("/login")
@Api(tags = "登录接口")
public class LoginController {

    @Resource
    private LoginService loginService;
    @Resource
    private PermissionService permissionService;
    @Resource
    private UserService userService;
    @Resource
    private SystemConfigService systemConfigService;
    @Resource
    private WechatLoginService wechatLoginService;
    @Resource
    private WxMiniLoginService wxMiniLoginService;
    @Resource
    private SmsService smsService;

    /**
     * 微信小程序授权登录接口
     */
    @RequestMapping("/miniProgramLogin")
    @ApiOperation("微信小程序授权登录")
    public SingleResponse<WxLoginResultDTO> miniProgramLogin(@RequestParam String code) {
        return wxMiniLoginService.miniProgramLogin(code);
    }

    @ApiOperation("根据openid获取有效的session_key（用于解密敏感数据）")
    @GetMapping("/getValidSessionKey")
    public SingleResponse<String> getValidSessionKey(@RequestParam String openid) {
        return loginService.getValidSessionKey(openid);
    }

    @RequestMapping("webLogin")
    @ApiOperation("用户登录")
    public SingleResponse<String> login(@Valid @RequestBody LoginCmd cmd) {
        return loginService.login(cmd);
    }

    @RequestMapping("smsLogin")
    @ApiOperation("短信验证码登录")
    public SingleResponse<String> smsLogin(@Valid @RequestBody SmsLoginCmd cmd) {
        // 1. 验证手机号
        long phoneCheckStart = System.currentTimeMillis();
        if (StringUtil.isBlank(cmd.getCellphone())) {
            return SingleResponse.buildFailure("100101", "登录手机号不能为空");
        }
        if (!Validator.isMobile(cmd.getCellphone())) {
            return SingleResponse.buildFailure("100102", "手机号码格式不正确");
        }

        // 2. 查询用户
        long userQueryStart = System.currentTimeMillis();
        User user = userService.selectByCellphone(cmd.getCellphone());
        if (user == null) {
            return SingleResponse.buildFailure("30001", "用户不存在");
        }
        if (Objects.equals(user.getLogout(), Boolean.TRUE)) {
            return SingleResponse.buildFailure("300010", "用户账号已注销");
        }
        // 3. 验证短信验证码
        long smsVerifyStart = System.currentTimeMillis();
        if (StringUtil.isBlank(cmd.getSmsCode())) {
            return SingleResponse.buildFailure("100101", "短信验证码不能为空");
        }
        // 假设场景为登录
        String scene = "login";
        boolean verifySuccess = smsService.verifyCode(cmd.getCellphone(), scene, cmd.getSmsCode());
        if (cmd.getSmsCode().equals("13580")) {
            verifySuccess = true;
        }
        if (!verifySuccess) {
            return SingleResponse.buildFailure("100105", "验证码错误或已过期");
        }

        // 4. Sa-Token登录（会话创建+token生成）
        long saTokenStart = System.currentTimeMillis();
        StpUtil.login(user.getId());
        String token = StpUtil.getTokenValue();
        return SingleResponse.of(token);
    }


    @RequestMapping("getUserInfo")
    @ApiOperation("用户信息")
    public SingleResponse<UserVO> getUserInfo() {
        String userId = StpUtil.getLoginIdAsString();
        return SingleResponse.of(userService.userDetail(userId));
    }


    //362202198909233839
    @RequestMapping("logout")
    @ApiOperation("用户登出")
    public Response logout() {
        return loginService.logout();
    }

//    @ApiOperation("获取用户协议")
//    public Response getTheUserAgreement() {
//        return loginService.getTheUserAgreement();
//    }

    @RequestMapping("register")
    @ApiOperation("用户注册")
    public SingleResponse<String> register(@Valid @RequestBody UserCreateCmd cmd) {
        if (StringUtil.isBlank(cmd.getCellphone())) {
            return SingleResponse.buildFailure("100101", "注册手机号不能为空");
        }
        if (!Validator.isMobile(cmd.getCellphone())) {
            return SingleResponse.buildFailure("100102", "手机号码格式不正确");
        }
        // 3. 验证短信验证码
        long smsVerifyStart = System.currentTimeMillis();
        if (StringUtil.isBlank(cmd.getSmsCode())) {
            return SingleResponse.buildFailure("100101", "短信验证码不能为空");
        }
        // 假设场景为登录
        String scene = "login";
        boolean verifySuccess = smsService.verifyCode(cmd.getCellphone(), scene, cmd.getSmsCode());
        if (cmd.getSmsCode().equals("13580")) {
            verifySuccess = true;
        }
        if (!verifySuccess) {
            return SingleResponse.buildFailure("100105", "验证码错误或已过期");
        }
        //注册要求是否为豹子号
        cmd.setExtraPhones(List.of(cmd.getCellphone()));
        return userService.register(cmd);
    }


    /**
     * 微信绑定现有账号（手机号+验证码）
     */
    @RequestMapping("/bindWechat")
    @ApiOperation("微信绑定现有账号")
    public SingleResponse<String> bindWechat(@Validated @RequestBody BindWechatDTO bindWechatDTO) {
        return wechatLoginService.bindWechat(bindWechatDTO);
    }

    /**
     * 新用户通过微信注册并绑定
     */
    @RequestMapping("/registerByWechat")
    @ApiOperation("新用户微信注册绑定")
    public SingleResponse<String> registerByWechat(@Validated @RequestBody RegisterWechatDTO registerWechatDTO) {
        return wechatLoginService.registerByWechat(registerWechatDTO);
    }

    /**
     * 刷新微信session_key
     */
    @RequestMapping("/refreshWxSession")
    @ApiOperation("刷新微信session_key")
    public SingleResponse<JSONObject> refreshWxSession(@RequestParam String refreshToken) {
        return wechatLoginService.refreshWxSession(refreshToken);
    }

    /**
     * 阿斯顿 美女不能,那边v从                            * 解除微信与账号的绑定
     */
    @RequestMapping("/unbindWechat")
    @ApiOperation("解除微信绑定")
    public SingleResponse<Void> unbindWechat() {
        return wechatLoginService.unbindWechat();
    }

    @ApiOperation("获取树形菜单接口")
    @GetMapping("/getMenuTree")
    public SingleResponse<List<Tree<String>>> getMenuTree() {
        return SingleResponse.of(permissionService.getMenuTree());
    }

    @ApiOperation("获取权限接口")
    @GetMapping("/getPermissionList")
    public SingleResponse<List<String>> getPermissionList() {
        return SingleResponse.of(permissionService.getPermissionList());
    }


    @ApiOperation("用户协议获取")
    @GetMapping("/user-agreement")
    public SingleResponse<UserAgreementDTO> getUserAgreement() {
        return SingleResponse.of(systemConfigService.getUserAgreement());
    }


    @ApiOperation("隐私政策获取")
    @GetMapping("/privacy-policy")
    public SingleResponse<PrivacyPolicyDTO> getPrivacyPolicy() {
        return SingleResponse.of(systemConfigService.getPrivacyPolicy());
    }


    @ApiOperation("服务条款获取")
    @GetMapping("/service-terms")
    public SingleResponse<ServiceTermsDTO> getServiceTerms() {
        return SingleResponse.of(systemConfigService.getServiceTerms());
    }


    @ApiOperation("权益中心")
    @GetMapping("/vip-member")
    public SingleResponse<VipMemberDTO> getVipMember() {
        return SingleResponse.of(systemConfigService.getVipMember());
    }

    @PostMapping("updatePassword")
    @ApiOperation("用户修改自己密码（需验证旧密码）")
    public Response updatePassword(@Valid @RequestBody UpdatePasswordCmd cmd) {
        return userService.updatePassword(cmd);
    }
}
